I was given my first assignment as implementing inplace assignment operator for numpy arrays in Numba.
Numba converts jitted code to first a numba intermediate representation which in then lowered to LLVM code,
the code to do this transformation is in lowering.py file, there are functions like lower_binop etc which does that, if I find a function for inplace assignment I'll use that otherwise I'll have to write my self.
Report broken link in http://docs.scipy.org/doc/numpy/reference/index.html
Numba intermediate represenation for
@numba.jit(nopython=True)
def add_5(x):
y = x + 5
return y
is
---------------------------------IR DUMP: add_5---------------------------------
label 0:
x = arg(0, name=x) ['x']
$const0.2 = const(int, 5) ['$const0.2']
$0.3 = x + $const0.2 ['$0.3', '$const0.2', 'x']
del x []
del $const0.2 []
y = $0.3 ['$0.3', 'y']
del $0.3 []
$0.5 = cast(value=y) ['$0.5', 'y']
del y []
return $0.5 ['$0.5']
----------------------------IR DUMP: _broadcast_onto----------------------------
label 0:
src_ndim = arg(0, name=src_ndim) ['src_ndim']
src_shape = arg(1, name=src_shape) ['src_shape']
dest_ndim = arg(2, name=dest_ndim) ['dest_ndim']
dest_shape = arg(3, name=dest_shape) ['dest_shape']
$0.3 = src_ndim > dest_ndim ['$0.3', 'dest_ndim', 'src_ndim']
branch $0.3, 12, 16 ['$0.3']
label 12:
del src_shape []
del src_ndim []
del dest_shape []
del dest_ndim []
del $0.3 []
$const12.1 = const(int, 0) ['$const12.1']
$12.2 = cast(value=$const12.1) ['$12.2', '$const12.1']
del $const12.1 []
return $12.2 ['$12.2']
label 16:
del $0.3 []
$const16.1 = const(int, 0) ['$const16.1']
src_index = $const16.1 ['$const16.1', 'src_index']
del $const16.1 []
$16.4 = dest_ndim - src_ndim ['$16.4', 'dest_ndim', 'src_ndim']
del dest_ndim []
dest_index = $16.4 ['$16.4', 'dest_index']
del $16.4 []
jump 32 []
label 32:
jump 35 []
label 35:
$35.3 = src_index < src_ndim ['$35.3', 'src_index', 'src_ndim']
branch $35.3, 47, 163 ['$35.3']
label 47:
$47.3 = getitem(index=src_index, value=src_shape) ['$47.3', 'src_index', 'src_shape']
src_dim_size = $47.3 ['$47.3', 'src_dim_size']
del $47.3 []
$47.6 = getitem(index=dest_index, value=dest_shape) ['$47.6', 'dest_index', 'dest_shape']
dest_dim_size = $47.6 ['$47.6', 'dest_dim_size']
del $47.6 []
$const47.8 = const(int, 1) ['$const47.8']
$47.9 = dest_dim_size != $const47.8 ['$47.9', '$const47.8', 'dest_dim_size']
del $const47.8 []
branch $47.9, 79, 115 ['$47.9']
label 79:
del $47.9 []
$79.3 = src_dim_size != dest_dim_size ['$79.3', 'dest_dim_size', 'src_dim_size']
del dest_dim_size []
branch $79.3, 91, 140 ['$79.3']
label 91:
$const91.2 = const(int, 1) ['$const91.2']
$91.3 = src_dim_size != $const91.2 ['$91.3', '$const91.2', 'src_dim_size']
del $const91.2 []
branch $91.3, 103, 140 ['$91.3']
label 103:
del src_shape []
del src_ndim []
del src_index []
del src_dim_size []
del dest_shape []
del $91.3 []
del $79.3 []
del $35.3 []
$const103.2 = const(int, 1) ['$const103.2']
$103.3 = dest_index + $const103.2 ['$103.3', '$const103.2', 'dest_index']
del dest_index []
del $const103.2 []
$103.4 = unary(fn=-, value=$103.3) ['$103.3', '$103.4']
del $103.3 []
$103.5 = cast(value=$103.4) ['$103.4', '$103.5']
del $103.4 []
return $103.5 ['$103.5']
label 115:
del dest_dim_size []
del $47.9 []
$const115.2 = const(int, 1) ['$const115.2']
$115.3 = src_dim_size != $const115.2 ['$115.3', '$const115.2', 'src_dim_size']
del $const115.2 []
branch $115.3, 127, 140 ['$115.3']
label 127:
dest_shape[dest_index] = src_dim_size ['dest_index', 'dest_shape', 'src_dim_size']
del src_dim_size []
jump 140 []
label 140:
del src_dim_size []
del $79.3 []
del $115.3 []
$const140.2 = const(int, 1) ['$const140.2']
$140.3 = inplace_binop(lhs=src_index, rhs=$const140.2, fn=+) ['$140.3', '$const140.2', 'src_index']
del $const140.2 []
src_index = $140.3 ['$140.3', 'src_index']
del $140.3 []
$const140.5 = const(int, 1) ['$const140.5']
$140.6 = inplace_binop(lhs=dest_index, rhs=$const140.5, fn=+) ['$140.6', '$const140.5', 'dest_index']
del $const140.5 []
dest_index = $140.6 ['$140.6', 'dest_index']
del $140.6 []
jump 35 []
label 163:
del src_shape []
del src_ndim []
del src_index []
del dest_shape []
del $91.3 []
del $35.3 []
jump 164 []
label 164:
$164.2 = cast(value=dest_index) ['$164.2', 'dest_index']
del dest_index []
return $164.2 ['$164.2']
Yeah so I asked for help from Antoine and told that I can do the inplace addition as np.add(x, y, out=x) which sounds good. He asked me to look at register_binary_operator_kernel() in targets/npyimpl
There is a function numpy_ufunc_kernel which implements these ufunc it also has a keyword argument as explicit_output=True but no function uses that operator. After addition operation is called probably passed to an assignment operator, or maybe not?
Cool,